package com.fastloan.jn.mgt.process.service.impl;

import com.fastloan.jn.common.BasicServiceImpl;
import com.fastloan.jn.mgt.application.basic.enums.ApplicationStatus;
import com.fastloan.jn.mgt.application.basic.model.JnApplication;
import com.fastloan.jn.mgt.application.basic.service.JnApplicationService;
import com.fastloan.jn.mgt.process.core.ReturnData;
import com.fastloan.jn.mgt.process.dao.JnAppApproveMapper;
import com.fastloan.jn.mgt.process.exception.AppApproveException;
import com.fastloan.jn.mgt.process.model.JnAppApprove;
import com.fastloan.jn.mgt.process.model.JnAppApproveLog;
import com.fastloan.jn.mgt.process.model.JnAppApproveUser;
import com.fastloan.jn.mgt.process.model.JnApplicationApprovalReview;
import com.fastloan.jn.mgt.process.model.vo.AppApproveVo;
import com.fastloan.jn.mgt.process.model.vo.AppUserVO;
import com.fastloan.jn.mgt.process.service.AppApproveLogService;
import com.fastloan.jn.mgt.process.service.AppApproveService;
import com.fastloan.jn.mgt.process.service.AppApproveUserService;
import com.fastloan.jn.mgt.process.service.ApplicationApprovalReviewService;
import com.fastloan.jn.mgt.process.tactics.TacticsLinkService;
import com.fastloan.safe.mgt.user.model.CmuUser;
import com.fastloan.safe.mgt.user.service.CmuUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;


;import static com.fastloan.jn.mgt.application.basic.enums.ApplicationStatus.UNDER_REVIEW;
import static com.fastloan.jn.mgt.process.enums.TacticsType.APPROVE;
import static com.fastloan.jn.mgt.process.enums.TacticsType.USER_AUDITING;

/**
 * 进件审批实现类
 *
 * @author chenkai
 *         createTime 2017-02-2017/2/14 9:44
 */
@Service
public class AppApproveServiceImpl extends BasicServiceImpl<JnAppApprove> implements AppApproveService {
    @Autowired
    private JnAppApproveMapper appApproveDao;

    @Autowired
    private AppApproveLogService appApproveLogService;

    @Autowired
    private JnApplicationService tApplicationService;

    @Autowired
    private TacticsLinkService tacticsLinkService;

    @Autowired
    private CmuUserService userService;

    @Autowired
    private AppApproveUserService appApproveUserService;

    @Autowired
    private ApplicationApprovalReviewService applicationApprovalReviewService;

    /**
     * 审贷会
     */
    @Autowired
    private ApplicationApprovalReviewService tApplicationApprovalReviewService;

    @Override
    @Transactional
    public int insertApproval(JnAppApproveUser approveUser, ApplicationStatus applicationStatus) {
        String applicationId;
        if (approveUser.getAppApproveId() != null) {
            String appApproveId = approveUser.getAppApproveId();
            JnAppApprove appApprove = appApproveDao.selectByPrimaryKey(appApproveId);
            applicationId = appApprove.getAppId();
        } else {
            String approvalReviewId = approveUser.getApprovalReviewId();
            JnApplicationApprovalReview tApplicationApprovalReview = tApplicationApprovalReviewService.selectByPrimaryKey(approvalReviewId);
            applicationId = tApplicationApprovalReview.getAppId();
        }
        //更新进件状态
        if (null != applicationStatus) {
            tApplicationService.modifyApplicationStatus(applicationStatus, applicationId);
        }
        //添加日志信息
        JnAppApproveLog appApproveLog = new JnAppApproveLog();
        appApproveLog.setApplicationId(applicationId);
        appApproveLog.setAppApproveUserId(approveUser.getId());
        appApproveLog.setResult(approveUser.getApprovalConclution());
        appApproveLog.setCreateTime(new Date());
        appApproveLog.setUserId(approveUser.getUserId());
        appApproveLog.setIsReview(approveUser.getIsReview());
        return appApproveLogService.insertSelective(appApproveLog);
    }

    @Override
    @Transactional
    public ReturnData appApproveUserService(JnAppApproveUser appApproveUser, String applicationId) throws AppApproveException {
        appApproveUser.setCompleteTime(new Date());
        JnApplication tApplication = tApplicationService.selectByPrimaryKey(applicationId);
        tApplication.setApplicationStatus(UNDER_REVIEW.getType());
        tApplicationService.updateByPrimaryKeySelective(tApplication);
        JnAppApproveUser approveUserOne = new JnAppApproveUser();
        approveUserOne.setAppApproveId(appApproveUser.getAppApproveId());
        appApproveUser.setCompleteTime(new Date());
        if (appApproveUser.getApprovalReviewId() == null) {
            tacticsLinkService.runTactics(USER_AUDITING.getValue(), appApproveUser, applicationId);
        } else { //审贷会流程
            tacticsLinkService.runTactics(APPROVE.getValue(), appApproveUser, applicationId);
        }
        return new ReturnData(Boolean.TRUE);
    }

    @Override
    @Transactional
    public Integer deleteAppApprove(String application) {
        JnAppApprove approve = new JnAppApprove();
        approve.setAppId(application);
        List<JnAppApprove> approveList = appApproveDao.select(approve);
        for (JnAppApprove appApprove : approveList) {
            JnAppApproveUser appApproveUser = new JnAppApproveUser();
            appApproveUser.setAppApproveId(appApprove.getId());
            List<JnAppApproveUser> approveUserList = appApproveUserService.select(appApproveUser);
            for (JnAppApproveUser approveUser : approveUserList) { //删除用户审批表信息
                appApproveUserService.delete(approveUser);
            }

            JnApplicationApprovalReview approvalReview = new JnApplicationApprovalReview();
            approvalReview.setApprovalId(appApprove.getId());
            List<JnApplicationApprovalReview> approvalReviews = tApplicationApprovalReviewService.select(approvalReview);

            for (JnApplicationApprovalReview review : approvalReviews) {
                JnAppApproveUser appApproves = new JnAppApproveUser();
                appApproveUser.setApprovalReviewId(review.getId());
                List<JnAppApproveUser> appApproveList = appApproveUserService.select(appApproves);
                for (JnAppApproveUser approveUser : appApproveList) { //删除审批表信息
                    appApproveUserService.delete(approveUser);
                }
                tApplicationApprovalReviewService.delete(review); //删除审批表
            }
            appApproveDao.delete(appApprove); //删除审批链表
        }
        JnAppApproveLog appApproveLog = new JnAppApproveLog();
        appApproveLog.setApplicationId(application);
        return appApproveLogService.delete(appApproveLog); //删除审批日志
    }

    @Override
    public Boolean queryExamineApproving(String applicationId, String approveReviewId) {
        JnAppApproveUser appApproveUser = new JnAppApproveUser();
        appApproveUser.setApplicationId(applicationId);
        appApproveUser.setApprovalReviewId(approveReviewId);
        List<JnAppApproveUser> userList = appApproveUserService.select(appApproveUser);
        return userList.stream().allMatch(approveUser -> approveUser.getStatus().equals(0));
    }

    @Override
    public List<AppApproveVo> getApproveChain(String applicationId, int flag) throws AppApproveException {
        List<AppApproveVo> appApproveVoList = new ArrayList<>(); //审批链VO类
        Example example = new Example(JnAppApprove.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("appId", applicationId);
        if (flag == 0) { //查询当前审批节点
            criteria.andCondition("STATUS IN (1, 2)");
        }
        List<JnAppApprove> appApproveList = appApproveDao.selectByExample(example);

        if (!appApproveList.isEmpty()) {
            Map<String, List<JnAppApprove>> personGroups = appApproveList.stream()
                    .collect(Collectors.groupingBy(JnAppApprove::getApproveGroup));

            for (Map.Entry<String, List<JnAppApprove>> entry : personGroups.entrySet()) {
                List<JnAppApprove> appApproves = entry.getValue();    //appApproves为完整的审批流程
                try {
                    appApproveVoList = queryApproveUser(appApproves);
                } catch (AppApproveException e) {
                    e.printStackTrace();
                    throw new AppApproveException("无法获取审批角色信息");
                }

            }
        }
        return appApproveVoList;
    }

    /**
     * 查询审批节点中具体审批信息
     *
     * @param appApproves 审贷会人员信息
     * @return 审贷会信息
     * @throws AppApproveException 查询审批异常
     */
    private List<AppApproveVo> queryApproveUser(List<JnAppApprove> appApproves) throws AppApproveException {
        List<AppApproveVo> appApproveVoList = new ArrayList<>(); //审批链VO类
        int appApproveCount;
        JnAppApprove approveOne = new JnAppApprove();
        for (JnAppApprove approve : appApproves) { //遍历所有审批节点
            approveOne.setApproveGroup(approve.getApproveGroup());
            appApproveCount = appApproveDao.selectCount(approveOne);
            AppApproveVo appApproveVo = new AppApproveVo();
            appApproveVo.setAppApprove(approve); //插入审批链信息
            appApproveVo.setProgress(approve.getApproveSort() + "/" + appApproveCount); //设置当前审批进度
            String approveRoles = approve.getApproveRoles();
            if (approve.getLoanMeeting().equals(0)) {
                AppApproveVo userFlow = UserFlow(approveRoles, approve, appApproveVo);
                appApproveVoList.add(userFlow);
            } else { //审贷会
                AppApproveVo approvalFlow = ApprovalFlow(approve, appApproveVo);
                appApproveVoList.add(approvalFlow);
            }
        }
        return appApproveVoList;
    }

    /**
     * 非审贷会
     *
     * @param userIds      用户id组
     * @param approve      流程表
     * @param appApproveVo VO类
     * @return 审批信息
     */
    private AppApproveVo UserFlow(String userIds, JnAppApprove approve, AppApproveVo appApproveVo) {
        String[] strings = userIds.split(","); //获取审批流程中的所有审批角色
        List<AppUserVO> collect = Arrays.stream(strings)
                .map(userId -> {
                    AppUserVO userVO = new AppUserVO();
                    CmuUser user = userService.selectByPrimaryKey(userId);
                    if (user != null) {
                        JnAppApproveUser approveUser = new JnAppApproveUser();
                        approveUser.setUserId(userId);
                        approveUser.setAppApproveId(approve.getId());
                        List<JnAppApproveUser> appApproveUserList = appApproveUserService.select(approveUser);//具体审批信息
                        userVO.setAppApproveUserList(appApproveUserList); //插入审核人员具体审核信息
                        userVO.setUser(user);
                    }
                    return userVO; //所有审核人员信息
                }).collect(Collectors.toList());
        appApproveVo.setAppUserVOList(collect);
        return appApproveVo;
    }

    /**
     * 审贷会排审
     *
     * @param approve      流程表
     * @param appApproveVo VO类
     * @return 审批信息
     */
    private AppApproveVo ApprovalFlow(JnAppApprove approve, AppApproveVo appApproveVo) {
        JnAppApproveUser approveUser = new JnAppApproveUser();
        JnApplicationApprovalReview tApplicationApprovalReview = new JnApplicationApprovalReview();
        tApplicationApprovalReview.setApprovalId(approve.getId());
        JnApplicationApprovalReview applicationApprovalReview = applicationApprovalReviewService.selectOne(tApplicationApprovalReview);//审贷会信息
        if (applicationApprovalReview != null) {
            approveUser.setApprovalReviewId(applicationApprovalReview.getId());
        }
        List<AppUserVO> appUserVOS = new ArrayList<>();
        List<JnAppApproveUser> appApproveUsers = appApproveUserService.select(approveUser);
        for (JnAppApproveUser appApproveUser : appApproveUsers) {
            AppUserVO userVO = new AppUserVO();
            CmuUser user = userService.selectByPrimaryKey(appApproveUser.getUserId());
            userVO.setUser(user);
            userVO.setAppApproveUserList(appApproveUsers);
            appUserVOS.add(userVO);
        }
        appApproveVo.setAppUserVOList(appUserVOS);
        return appApproveVo;
    }

}
